package com.roy.minimq.broker.application;

import com.roy.minimq.broker.domain.out.BrokerOutAPI;
import com.roy.minimq.common.ThreadFactoryImpl;
import com.roy.minimq.common.broker.BrokerConfig;
import com.roy.minimq.remoting.domain.nettyclient.NettyClientConfig;
import com.roy.minimq.remoting.domain.nettyserver.NettyServerConfig;
import com.roy.minimq.remoting.domain.entity.RemotingServer;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class BrokerController {
    private BrokerConfig brokerConfig;
    private NettyServerConfig nettyServerConfig;
    private NettyClientConfig nettyClientConfig;
    private RemotingServer remotingServer;
    private BrokerOutAPI brokerOutAPI;
    private ScheduledExecutorService scheduledExecutor;

    public BrokerController(BrokerConfig brokerConfig, NettyServerConfig nettyServerConfig, NettyClientConfig nettyClientConfig) {
        this.brokerConfig = brokerConfig;
        this.nettyServerConfig = nettyServerConfig;
        this.nettyClientConfig = nettyClientConfig;
        this.brokerOutAPI = new BrokerOutAPI(nettyClientConfig);
        this.scheduledExecutor = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl("BrokerControllerScheduledThread"));
    }

    //TODO broker作为服务端需要进行一些组件初始化
    public boolean initialize() {
        boolean result = true;
        if (null != this.brokerConfig.getNamesrvAddr()) {
            this.brokerOutAPI.updateNameServerAddressList(this.brokerConfig.getNamesrvAddr());
        }
        return result;
    }

    //TODO broker启动
    public void start() {

        if (null != this.brokerOutAPI) {
            brokerOutAPI.start();
        }
        //正常是要在Broker启动完成后开始心跳注册。RocketMQ初始化设定10秒后开始心跳。这了broker简化了很多，就设置个3秒把。
        this.scheduledExecutor.scheduleAtFixedRate(() -> {
                    BrokerController.this.registerAll(false);
                }
                , 1000 * 3, brokerConfig.getRegisterNameServerPeriod(), TimeUnit.MILLISECONDS);
    }

    private void registerAll(Boolean oneway) {
        this.brokerOutAPI.registerBrokerAll(
                this.brokerConfig.getBrokerClusterName(),
                this.brokerConfig.getBrokerId() + ":" + this.brokerConfig.getListenPort(),
                this.brokerConfig.getBrokerName(),
                this.brokerConfig.getBrokerId(),
                false,
                this.brokerConfig.getRegisterBrokerTimeoutMills());
    }

    //TODO broker关闭
    public void shutdown() {
        this.brokerOutAPI.shutdown();
    }
}
